package com.tim;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tim.util.StringAnalysisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * string、变量互转
 */
@Slf4j
public class EntityHelper {
	@Test// 表实体转req、resp
	public void DO2ReqResp(){
		String code = "";
		String path =
				"D:\\github\\pharmacy-mall\\pharmacy-mall-service\\src\\main\\java\\com\\shp\\pharmacy\\mall\\service\\model\\LesseeOrderDetailsDO.java" +
						"";
		{ code="";
		}
		if(StringUtils.isNotBlank(path)){
			code = getClassBody(path);
		}
		String[] strs = code.split("[\r\n]+");
		String[] notPrintAttrs = new String[]{"gmtCreate", "modifyUserId", "gmtModified"};

		String annoVal = "";
		List<String> list = new ArrayList<>();
		for (int i = 0; i < strs.length; i++) {
			String str = strs[i];
			String item = str.trim();
			if(item.startsWith("@")){
				// 注解行
				item = "\t@ApiModelProperty(value = \""+annoVal+"\", required = true)";
				annoVal = "";
				list.add(item);
			}else if(item.startsWith("private")){
				// 属性行
				if(i>0 && !strs[i-1].trim().startsWith("@")){
					// 处理无@Column列
					item = "\t@ApiModelProperty(value = \""+annoVal+"\", required = true)\n"+item;
					annoVal = "";
				}
				if(StringUtils.containsAny(item, notPrintAttrs) && list.size()>1){
					list.remove(list.size()-1);
					continue;
				}
				item = item.replace("createUserId", "currentUserId");
				list.add(item);
			}else if(item.startsWith("public")){
				// 类、方法声明行
				if(item.contains(" class ")){
					continue;
				}
				throw new RuntimeException(item);
			}else{
				// 注释
				annoVal = annoVal + item.replaceAll("/\\*\\*", "")
						.replaceAll("\\*/", "")
						.replaceAll("\\*", "").trim();
			}
//			System.out.println(item);
		}
		list.forEach(System.out::println);
	}

	/**
	 * 生成请求参数、返回实体；无变量名时默认为varN
	 * 	translate插件翻译
	 */
	@Test
	public void genReqRespByInfo() throws IOException {
    String info = "生产批号 货单序号 省内id 地市id 区县id 买家手机 买家姓名 订单编号 生产时间" +
			"";
		int annoFlag = 1;// 1带swagger注解
		String className = "".trim();
    String[] lines = info.split("[\r\n\u200B\\s]+");
		int num = 1;// 辅助变量命名
    // 请求参数模板
    String reqVarTemplate =
        "    /**\n"
            + "     * REQ_VAR_DESC\n"
            + "     */\n"
            //		+ 		"    @Param(\"REQ_VAR_DESC\")\n"
			+ "    @ApiModelProperty(value = \"REQ_VAR_DESC\", notes = \"REQ_VAR_DESC\")\n"
            + "    private String REQ_VAR_NAME;\n\n";
		String reqVarTemplateNoAnno = "    /**\n" +
				"     * REQ_VAR_DESC\n" +
				"     */\n" +
				"    private String REQ_VAR_NAME;\n\n";
		String enumValidStr = "\n@EnumValidAnnotation(target = AvatarNicknameAuditStateEnum.class , skip = true)\n";
		String seeStr = "@see com.xqxc.pig.enums.account.BlockLogAccountTypeEnum\n\n";
//        System.out.println(enumValidStr);
//        System.out.println(seeStr);
		StringBuilder builder = new StringBuilder(); //.append(enumValidStr).append(seeStr);
		for(String line : lines){
//      		System.out.println(line);
			if(StringUtils.isBlank(line)){
				continue;
			}
			String[] infos = line.trim().split("\\s+");
			int length = infos.length;
			String varName = length>1 ? infos[0] : "var"+num++;
			String varDesc = length==2 ? infos[1] :
					length>1 ? line.substring(varName.length()) : line;
			String reqVarInfo = "";
			if(annoFlag==1){
				reqVarInfo = reqVarTemplate.replaceAll("REQ_VAR_DESC", varDesc)
						.replaceAll("REQ_VAR_NAME", varName);
			}else{
				reqVarInfo = reqVarTemplateNoAnno.replaceAll("REQ_VAR_DESC", varDesc)
						.replaceAll("REQ_VAR_NAME", varName);
			}
			builder.append(reqVarInfo);
		}
		String content = builder.toString();
		System.out.println(content);
		if(StringUtils.isNotBlank(className)){
			content = content.replace("@EnumValidAnnotation", "//@EnumValidAnnotation")
					.replace("@see ", "//@see ");
			content = String.format("public class %s { \n\n %s \n\n}", className, content);
			Files.write(Paths.get(MainHelper.OUTPUT_DIR, className+".java"), content.getBytes(StandardCharsets.UTF_8));
		}
	}

	@Test
	public void genByJson(){
    String json = "";// {json = "";}
		{
      json =
          "{\n" +
				  "            \"apiId\":\"api-c5zjvdbq\",              //网关分组 API 的 ID\n" +
				  "            \"groupId\":\"grp-60khzyb4\",            //网关分组ID（与 group.json 中的 groupId 保持一致时会认为该 API 属于该网关分组）\n" +
				  "            \"path\":\"/echo/{param}\",              //网关分组 API 的路径（也就是下游微服务的 API）\n" +
				  "            \"method\":\"GET\",\n" +
				  "            \"serviceName\":\"provider-demo\",       //网关下游的微服务名（也就是下游微服务的名称）\n" +
				  "            \"namespaceId\":\"namespace-v6m6pp5a\",\n" +
				  "            \"namespaceName\":\"test_namespace\",\n" +
				  "            \"usableStatus\":\"enabled\",\n" +
				  "            \"pathMapping\":\"/echo/{param}\",\n" +
				  "            \"apiType\":\"ms\"\n" +
				  "        }\n";
		}
    String descInfo = "";// {descInfo = "";}
		{
      descInfo =
          "";
		}
		Map<String, String> map = new HashMap<>();
		String[] descLines = descInfo.split("[\r\n]+");
		for(String descLine : descLines){
			if(StringUtils.isBlank(descLine)){
				continue;
			}
			String[] split = descLine.trim().split("\t");
			map.put(split[0].trim(), split.length<2?"":split[1]);
		}


		int annoFlag = 0;// 1带swagger注解
		// 请求参数模板
		String reqVarTemplate =
				"    /**\n"
						+ "     * REQ_VAR_DESC\n"
						+ "     */\n"
						//		+ 		"    @Param(\"REQ_VAR_DESC\")\n"
						+ "    @ApiModelProperty(value = \"REQ_VAR_DESC\", notes = \"REQ_VAR_DESC\")\n"
						+ "    private String REQ_VAR_NAME;\n\n";
		String reqVarTemplateNoAnno = "    /**\n" +
				"     * REQ_VAR_DESC\n" +
				"     */\n" +
				"    private String REQ_VAR_NAME;\n\n";
		String enumValidStr = "\n@EnumValidAnnotation(target = AvatarNicknameAuditStateEnum.class , skip = true)\n";
		String seeStr = "@see com.xqxc.pig.enums.account.BlockLogAccountTypeEnum\n\n";
//        System.out.println(enumValidStr);
//        System.out.println(seeStr);

		JSONObject jsonObject = JSON.parseObject(json);
		StringBuilder builder = new StringBuilder();//.append(enumValidStr).append(seeStr);
		for(String key : jsonObject.keySet()){
			String reqVarInfo;
			key = key.trim();
			if(annoFlag==1){
				reqVarInfo = reqVarTemplate.replaceAll("REQ_VAR_DESC", map.getOrDefault(key, key))
						.replaceAll("REQ_VAR_NAME", key);
			}else{
				reqVarInfo = reqVarTemplateNoAnno.replaceAll("REQ_VAR_DESC", map.getOrDefault(key, key))
						.replaceAll("REQ_VAR_NAME", key);
			}
			builder.append(reqVarInfo);
		}
		String content = builder.toString();
//		content = content.replaceAll("String ([^_]+)_price", "Integer $1_price")
//				.replaceAll("String ([^_]+)_id", "Long $1_id")
//				.replaceAll("String ((id;)|(stock;)|(sales;)|(price;)|(is_))", "Integer $1")
//				.replaceAll("", "")
//		;
    System.out.println(content);
	}

	/**
	 * 生成设置代码；cuEventInfoDO.setId(req.getId());
	 */
	@Test
	public void reqSetDOCode() throws IOException {
		String destName = "op";
		String sourceName = "";// 空时set为""
    String path =
        "D:\\github\\pharmacy-mall\\pharmacy-mall-service\\src\\main\\java\\com\\shp\\pharmacy\\mall\\service\\model\\OperationInfo.java" +
				"";
		String code = "";
		{
			code="";
		}
		if(StringUtils.isNotBlank(path)){
			code = getClassBody(path);
		}
		List<String> currentUserIdVars = Arrays.asList("CreateUserId", "ModifyUserId");
		List<String> nowVars = Arrays.asList("GmtCreate", "GmtModified");
		Arrays.stream(code.split("\n"))
				.map(String::trim)
				.filter(item->item.startsWith("private"))
				.map(item->{
					String[] strs = item.split("\\s");
					String fieldName = strs[2].replace(";", "");
					// 首字母转大写
					fieldName = StringAnalysisUtil.head2UpperCase(fieldName);
					if(currentUserIdVars.contains(fieldName)){
						return String.format("%1$s.set%3$s(AdminLoginContext.get().getUserId());", destName, sourceName, fieldName);
					}else if(nowVars.contains(fieldName)){
						return String.format("%1$s.set%3$s(new Date());", destName, sourceName, fieldName);
					}
					if(StringUtils.isBlank(sourceName)){
						return String.format("%1$s.set%3$s(\"\");", destName, sourceName, fieldName);
					}
					return String.format("%1$s.set%3$s(%2$s.get%3$s());", destName, sourceName, fieldName);
				})
				.forEach(System.out::println);

	}

	@Test// 表实体转req、resp
	public void getRespDoc(){
		String code = "";
		String path =
				"D:\\github\\pharmacy-mall\\pharmacy-mall-service\\src\\main\\java\\com\\shp\\pharmacy\\mall\\service\\model\\LesseeOrderDetailsDO.java" +
						"";
		{ code="";
		}
		if(StringUtils.isNotBlank(path)){
			code = getClassBody(path);
		}
		String[] strs = code.split("[\r\n]+");
		String[] notPrintAttrs = new String[]{"gmtCreate", "modifyUserId", "gmtModified"};

		String annoVal = "";
		List<String> list = new ArrayList<>();
		for (int i = 0; i < strs.length; i++) {
			String str = strs[i];
			String item = str.trim();
			if(item.startsWith("@")){
				// 注解行

			}else if(item.startsWith("private")){
				// 属性行
				if(StringUtils.containsAny(item, notPrintAttrs)){
					continue;
				}
				String[] fieldInfo = StringAnalysisUtil.getFieldInfo(item);
				String type = fieldInfo[1].toLowerCase();
				type = "boolean".equals(type) ? "boolean"
						: Arrays.asList("string,date".split(",")).contains(type) ? "string"
						: Arrays.asList("byte,short,int,integer,long,float,double".split(",")).contains(type) ? "number"
						: "object";
				list.add(String.format("%s\t%s\t%s", fieldInfo[2], type, annoVal));
				annoVal = "";
			}else if(item.startsWith("public")){
				// 类、方法声明行
				if(item.contains(" class ")){
					continue;
				}
				break;
			}else{
				// 注释
				annoVal = annoVal + item.replaceAll("/\\*\\*", "")
						.replaceAll("\\*/", "")
						.replaceAll("\\*", "").trim();
			}
//			System.out.println(item);
		}
		list.forEach(System.out::println);
	}

	@Test// 比较json字段
	public void compareJsonField(){
		String json1="", json2="";// {json = "";}
		{
      json1 =
          "{\n"
              + "            \"id\": 480,\n"
              + "            \"order_id\": 397,\n"
              + "            \"title\": \"ceshi0802供应商的商品1\",\n"
              + "            \"sku_title\": \"默认\",\n"
              + "            \"unit\": \"\",\n"
              + "            \"qty\": 1,\n"
              + "            \"amount\": 8000,\n"
              + "            \"price\": 8000,\n"
              + "            \"image_url\": \"https://supply-chain-yunzmall.oss-cn-beijing.aliyuncs.com/20211027/1635325820QQ截图20211007105506.png\",\n"
              + "            \"product_id\": 1028721,\n"
              + "            \"supply_amount\": 10000,\n"
              + "            \"sku_id\": 21139,\n"
              + "            \"order_express_id\": 99,\n"
              + "            \"comment_status\": 0,\n"
              + "            \"refund_status\": 0,\n"
              + "            \"can_refund\": 0,\n"
              + "            \"refund_amount\": 0,\n"
              + "            \"send_status\": 1,\n"
              + "            \"options\": [\n"
              + "              {\n"
              + "                \"spec_name\": \"规格\",\n"
              + "                \"spec_item_name\": \"默认\"\n"
              + "              }\n"
              + "            ]\n"
              + "          }";
		}
		{
      json2 =
          "{\n"
              + "            \"id\": 479,\n"
              + "            \"created_at\": 1635749996,\n"
              + "            \"updated_at\": 1635749996,\n"
              + "            \"key\": \"\",\n"
              + "            \"title\": \"ceshi0802供应商的商品1\",\n"
              + "            \"sku_title\": \"默认\",\n"
              + "            \"unit\": \"\",\n"
              + "            \"qty\": 1,\n"
              + "            \"amount\": 8000,\n"
              + "            \"discount_amount\": 0,\n"
              + "            \"deduction_amount\": 0,\n"
              + "            \"cost_amount\": 10000,\n"
              + "            \"payment_amount\": 8000,\n"
              + "            \"supply_amount\": 10000,\n"
              + "            \"image_url\": \"https://supply-chain-zhongtai.oss-cn-beijing.aliyuncs.com/20211027/1635325820QQ截图20211007105506.png\",\n"
              + "            \"send_status\": 0,\n"
              + "            \"trade_id\": 0,\n"
              + "            \"supplier_id\": 12,\n"
              + "            \"user_id\": 35,\n"
              + "            \"order_id\": 396,\n"
              + "            \"product_id\": 1028721,\n"
              + "            \"sku_id\": 21137,\n"
              + "            \"original_sku_id\": 0,\n"
              + "            \"order_express_id\": 0,\n"
              + "            \"amount_detail\": {\n"
              + "              \"title\": \"\",\n"
              + "              \"amount\": 0,\n"
              + "              \"qty\": 0,\n"
              + "              \"desc\": \"\",\n"
              + "              \"amount_items\": [\n"
              + "                {\n"
              + "                  \"title\": \"商品等级优惠\",\n"
              + "                  \"amount\": -2000,\n"
              + "                  \"qty\": 0,\n"
              + "                  \"desc\": \"\",\n"
              + "                  \"amount_items\": []\n"
              + "                },\n"
              + "                {\n"
              + "                  \"title\": \"商品总价\",\n"
              + "                  \"amount\": 8000,\n"
              + "                  \"qty\": 0,\n"
              + "                  \"desc\": \"\",\n"
              + "                  \"amount_items\": []\n"
              + "                }\n"
              + "              ]\n"
              + "            },\n"
              + "            \"options\": [\n"
              + "              {\n"
              + "                \"spec_name\": \"规格\",\n"
              + "                \"spec_item_name\": \"默认\"\n"
              + "              }\n"
              + "            ],\n"
              + "            \"sku\": {\n"
              + "              \"id\": 0,\n"
              + "              \"created_at\": null,\n"
              + "              \"updated_at\": null,\n"
              + "              \"title\": \"\",\n"
              + "              \"price\": 0,\n"
              + "              \"cost_price\": 0,\n"
              + "              \"origin_price\": 0,\n"
              + "              \"guide_price\": 0,\n"
              + "              \"activity_price\": 0,\n"
              + "              \"stock\": 0,\n"
              + "              \"weight\": 0,\n"
              + "              \"is_display\": 0,\n"
              + "              \"product_id\": 0,\n"
              + "              \"supplier_id\": 0,\n"
              + "              \"sn\": \"\",\n"
              + "              \"image_url\": \"\",\n"
              + "              \"options\": null,\n"
              + "              \"original_sku_id\": 0\n"
              + "            }\n"
              + "          }";
		}
		JSONObject jsonObject1 = JSON.parseObject(json1);
		JSONObject jsonObject2 = JSON.parseObject(json2);
		Set<String> set1 = jsonObject1.keySet();
		Set<String> set2 = jsonObject2.keySet();

		if(set1.containsAll(set2) && set2.containsAll(set1)){
			return;
		}
		HashSet<String> newSet1 = new HashSet<>(set1);
		HashSet<String> newSet2 = new HashSet<>(set2);
    	System.out.println("SET1:");
		newSet1.removeAll(set2);
		if(CollectionUtils.isNotEmpty(newSet1)){
			System.out.println(newSet1);
		}
		System.out.println("SET2:");
		newSet2.removeAll(set1);
		if(CollectionUtils.isNotEmpty(newSet2)){
			System.out.println(newSet2);
		}
	}

	/**req转json字符串*/
	@Test
	public void printJsonByCode() {
		String code = "";
		String path = "E:\\gitlab\\exodus\\biz\\biz-pig\\biz-pig-bean\\src\\main\\java\\com\\xqxc\\pig\\bean\\biz\\request\\account\\UpdateSmallTransportBusinessLicenseReq.java" +
				"";
		{ code=" ";}
		if(StringUtils.isNotBlank(path)){
			code = getClassBody(path);
		}

		StringBuilder builder = new StringBuilder("{\n");
		StringAnalysisUtil.getFieldNameList(code).stream()
			.map(item->String.format("  \"%s\": \"\",\n", item))
			.forEach(builder::append);
		String result = builder.toString().replaceAll(",\\s*$", "");
		System.out.println(result+"\n}");
	}

	@Test
	public void printJsonField(){
    String json =
        "{\n"
            + "  \"platService\": 1,\n"
            + "  \"technologyService\": 1,\n"
            + "  \"promote\": 1,\n"
            + "  \"subtotal\": 1,\n"
            + "  \"favorite\": 1,\n"
            + "  \"market\": 1,\n"
            + "  \"free\": 1,\n"
            + "  \"salesRevenue\": 1,\n"
            + "  \"advertise\": 1,\n"
            + "  \"showPromote\": 1,\n"
            + "  \"systemService\": 1,\n"
            + "  \"systemAdvert\": 1,\n"
            + "  \"merchantService\": 1,\n"
            + "  \"regionManage\": 1,\n"
            + "  \"regionNature\": 1,\n"
            + "  \"opCenterManage\": 1,\n"
            + "  \"opCenterNature\": 1,\n"
            + "  \"platDistribution\": 1,\n"
            + "  \"distributionTransfer\": 1,\n"
            + "  \"serviceExpand\": 1,\n"
            + "  \"serviceShare\": 1,\n"
            + "  \"salesmanDistribution\": 1,\n"
            + "  \"platSalesTransfer\": 1,\n"
            + "  \"distributionService\": 1,\n"
            + "  \"serviceDistribution\": 1,\n"
            + "  \"shopPlusPrice\": 1,\n"
            + "  \"favoriteSelect\": 1,\n"
            + "  \"costBenefit\": 1,\n"
            + "  \"consignmentBenefit\": 1\n"
            + "}";
		JSONObject jsonObject = JSON.parseObject(json);
		String fields = jsonObject.keySet().stream().collect(Collectors.joining(","));
    	System.out.println(fields);
	}

	/**
	 * 转表格展示；打开链接，替换columns、data
	 * https://codesandbox.io/s/ji-ben-yong-fa-antd-4-17-0-alpha-0-forked-92cee?file=/index.js
	 */
	@Test
	public void result2AntTable(){
		/* step1，填写展示属性、表格请求结果*/
		// 为空时，默认展示全部属性
		String showInfo = "";
		String jsonStr = "{\"cmd\":\"com.xqxc.api.pigear.biz.account.AddressManageService.listConsigneeAddress\",\"group\":\"earPc\",\"errCode\":0,\"errName\":\"OK\",\"result\":[{\"id\":2132202348192139,\"accountId\":2131535439831913,\"consigneeName\":\"hello\",\"consigneeMobile\":\"18716941108\",\"areaId\":500112,\"cityId\":500100,\"provinceId\":500000,\"address\":\"金桂路 象屿两江望府 14层202\",\"addressDetail\":\"重庆市,重庆市,渝北区\",\"hourseAddress\":\"14层202\",\"amapStreet\":\"金桂路\",\"lng\":106.533838,\"lat\":29.642923,\"mapAddress\":\"象屿两江望府\"}]}" +
				"";

		/* step2，转换为ant格式*/
		JSONArray data;
		try{
			data = JSON.parseObject(jsonStr).getJSONArray("result");
		}catch (ClassCastException e){
			data = JSON.parseObject(jsonStr)
					.getJSONObject("result").getJSONArray("dataList");
		}
		String result = data.toJSONString();
		String columnsTemplate = " { title: 'FIELD_NAME', dataIndex: 'FIELD_NAME', key: 'FIELD_NAME', },";
		StringBuilder columns = new StringBuilder("[ ");
		if(StringUtils.isBlank(showInfo)){
			showInfo = data.getString(0).replaceAll("\\s+", "");
			// 去除{}，按:分割为数组；获取最后一个逗号后内容作为field
			String[] strs = showInfo.substring(showInfo.indexOf('{')+1, showInfo.lastIndexOf('}'))
					.split(":");
			showInfo = Arrays.stream(strs)
					.limit(strs.length-1)
					.map(item -> {
						int idx = item.lastIndexOf(',');
						return idx > 0 ? item.substring(idx + 1) : item;
					}).collect(Collectors.joining("\n"));

		}
		List<String> list = Arrays.stream(showInfo.split("\n"))
				.filter(StringUtils::isNotBlank)
				.map(item->{
					item = item.trim();
					if(item.startsWith("\"")){
						item = item.substring(1, item.indexOf("\"", 2));
					}else if(item.startsWith("'")){
						item = item.substring(1, item.indexOf("'", 2));
					}
					return item;
				})
				.collect(Collectors.toList());
		for (String item : list) {
			columns.append(columnsTemplate.replaceAll("FIELD_NAME", item));
		}
		columns.append(" ]");
		System.out.println(String.format("\nconst columns=%s;\nconst data = %s;\n",
				columns.toString(), result));
	}

    private String getClassBody(String path){
		return StringAnalysisUtil.getClassInfo(path, false).get(2);
	}
}
